package chat_server;

import for_all.Message;
import for_all.PrivateChat;
import for_all.Room;
import for_all.Room.UserChangedRoom;
import for_all.Transporter;
import for_all.User;
import for_all.User.LogOutUser;
import java.util.ArrayList;


public class UserClientHandler extends Thread {
    
    // -------------------------------------------------------------------------
    // Variablendeklarationen
    private Transporter transporter;
    private ManageUser  mangUsr;
    private ManageRooms mangRms;
    private User        user;
    
    // -------------------------------------------------------------------------
    // Konstruktor
    public UserClientHandler (User user, Transporter trans, ManageUser mangUsr, ManageRooms mangRms) {
        
        this.user = user;
        this.transporter = trans;
        this.mangUsr = mangUsr;
        this.mangRms = mangRms;
        
    } 
    
    
    // -------------------------------------------------------------------------
    // Thread zum Verarbeiten von Netzwerkkommunikationen
    @Override
    public void run () {
      
        while (!this.isInterrupted()) {
          Object receivedMessage = transporter.receiveObject();
           
          
          // Message empfangen und verteilen
          if(receivedMessage instanceof Message) {
                   
              Message msg = (Message) receivedMessage;
                    
              if (msg.getPrivate()) {
                  mangUsr.sendMessageToClient(msg.getRoomName().substring(14), msg);
              } else {
                if(msg.getRoomName() == null) {
                    mangUsr.sendMessageToAllUser(msg);
                } else {
                    mangRms.sendMessageToAllUserInRoomWithout(msg.getRoomName(), msg, msg.getSender());  //wenn sich der user in einem raum befindet
                }
              }
              
              
          // Client hat sich ausgeloggt
          } else if (receivedMessage instanceof User.LogOutUser) {
              this.mangUsr.logOut(user, true);
            
              
          //  PrivatChat starten
          } else if (receivedMessage instanceof PrivateChat){
              
              // Private Chat bei beiden Usern hinzufügen
              this.user.addPrivateChat((PrivateChat)receivedMessage);
              this.mangUsr.getUser(((PrivateChat)receivedMessage).getUser2()).addPrivateChat((PrivateChat)receivedMessage);
              this.mangRms.getGui().setMessage(new Message(user.getUserName() + " startete einen privaten Raum mit " + ((PrivateChat)receivedMessage).getUser2(), "Admin", "Server", false));
              
          // anderen Raum beitreten
          } else if(receivedMessage instanceof Room.userJoinsRoom) {
                    
                Room dummy = new Room("dummy");
                dummy.setUserJoinsRoom((Room.userJoinsRoom)receivedMessage);
                String userName = dummy.getuserJoinsRoom().getUserName();
                String roomName = dummy.getuserJoinsRoom().getRoomName();
                
                // User ist bereits in diesem Raum
                if (mangUsr.getUser(userName).getRoomName() != null && mangUsr.getUser(userName).getRoomName().compareTo(roomName) == 0) {
                    
                    ArrayList<String> names = mangRms.getUserNames(roomName);
                    names.remove(userName);
                    
                    // Liste der aktuellen Clients in diesem Raum senden (außer dem anfragenden User)
                    this.sendStringList(names);
                    
                    // Wenn man den user nicht wieder hinzufügt, kommt es zu fehlern -.-
                    names.add(userName);
                    
                    // Continue beendet diesen Schleifendurchlauf
                    continue;
                }
                
                // User aus Raum entfernen
                if("--null--".compareTo(mangUsr.getUser(userName).getRoomName()) != 0) { //falls user bereits in einem anderen raum war
                    mangRms.removeUser(mangUsr.getUser(userName).getRoomName(), mangUsr.getUser(userName));
                }
                
                // Liste der User in dem Raum an den Client senden
                this.sendStringList(mangRms.getUserNames(roomName));
                
                
                // User dem Raum hinzufügen
                mangRms.addUser(roomName, mangUsr.getUser(userName));
                
                // Raumnamen im UserObjekt setzen
                mangUsr.getUser(userName).setRoom(roomName);
                mangUsr.informAllUserAboutUserChangedRoom(userName, roomName);
                
                
            // wenn Client eine Liste aller Räume haben will    
            } else if (receivedMessage instanceof Room.getRoomNames) {
            
                Room dummy = new Room("dummy");
                dummy.setGetRoomNames((Room.getRoomNames)receivedMessage);
                String userName = dummy.getGetRoomNames().getUserName();
                    
                ArrayList<String> liste = mangRms.getRoomNames();
                this.sendStringList(liste);
            
            
            // Privaten Raum entfernen
            } else if (receivedMessage instanceof PrivateChat.RemovePrivateChat) {
                
                this.mangUsr.getUser(((PrivateChat.RemovePrivateChat)receivedMessage).otherUser).removePrivateChat((PrivateChat.RemovePrivateChat)receivedMessage);
                this.user.removePrivateChat((PrivateChat.RemovePrivateChat)receivedMessage);
                this.mangRms.getGui().setMessage(new Message(user.getUserName() + " beendete den privaten Raum mit " + ((PrivateChat.RemovePrivateChat)receivedMessage).otherUser, "Admin", "Server", false));
            }
        }
    }
        
    
    // -------------------------------------------------------------------------
    // Objekt an User schicken
    private boolean sendObjectToUser (Object o) {
        this.transporter.sendObject(o);
        return true;
    }
        

    // -------------------------------------------------------------------------
    // UserLoggedOn an User schicken
    public void sendNewUserLoggedOn(String usr, String room) {
        this.sendObjectToUser(new User.NewUserLoggedOn(usr, room));  
    }
    
    
    // -------------------------------------------------------------------------
    //UserLoggedOff an User schicken
    public void sendUserLoggedOff(String usr, String room) {
        this.sendObjectToUser(new User.UserLoggedOff(usr, room));
    }
    
    
    // -------------------------------------------------------------------------
    //informiert Client über Raumwechsel
    public void sendUserChangedRoom(String userName, String roomName) {
        this.sendObjectToUser(new UserChangedRoom(userName, roomName));
    }
    
    
    // -------------------------------------------------------------------------    
    // Nachricht an User schicken
    public void sendMessageToClient(Message msg) {
        this.sendObjectToUser(msg);
    }
        
    
    // -------------------------------------------------------------------------    
    // LogOut an User schicken
    public void sendLogOutToUser(LogOutUser.LogoutReason reason, boolean serverNotification) {
        this.sendObjectToUser(new LogOutUser(reason));
        this.mangUsr.logOut(this.user, serverNotification);
    }
        
        
    // -------------------------------------------------------------------------
    // String-Liste schicken
    public void sendStringList(ArrayList<String> liste) {
        if (this.sendObjectToUser(liste) == true) {
            this.transporter.reset();
        }
    }
        
       
    // -------------------------------------------------------------------------
    // User über neuen User im Raum informieren
    public void informUserAboutNewUserInRoom(String newUser) {
        Room dummy = new Room("dummy");
        dummy.setNewUserInRoom(newUser);
        sendObjectToUser(dummy.getNewUserInRoom());
    }
        
    
    // -------------------------------------------------------------------------
    // User darüber informieren, dass ein anderer User den Raum verlassen hat
    public void informUserAboutUserLeaved(String userName) {
        Room dummy = new Room("dummy");
        dummy.setUserLeavedRoom(userName);
        sendObjectToUser(dummy.getUserLeavedRoom());
    }
        
        
    // -------------------------------------------------------------------------
    // User über neuen Raum informieren
    public void informUserAboutNewRoom(String roomName) {
        Room dummy = new Room(roomName);
        dummy.setRoomCreated(roomName);
        sendObjectToUser(dummy.getRoomCreated());
    }
    
    
    // -------------------------------------------------------------------------
    // User über gelöschten Raum informieren
    public void informUserAboutDeletedRoom(String roomName) {
        Room dummy = new Room(roomName);
        dummy.setRoomDeleted(roomName);
        sendObjectToUser(dummy.getRoomDeleted());
    }
       
        
    // -------------------------------------------------------------------------
    // User über geänderten Namen informieren
    public void informUserAboutRoomNameChanged(String oldName, String newName) {
        Room dummy = new Room(oldName);
        dummy.setRoomNameChanged(oldName, newName);
        sendObjectToUser(dummy.getRoomNameChanged());
    }
    
    
    // -------------------------------------------------------------------------
    // informiert User über neuen Private Chat
    public void informUserAboutPrivateChat (PrivateChat privChat) {
        this.sendObjectToUser(privChat.getInformMessage());
    }
    
    
    // -------------------------------------------------------------------------
    // user über gelöschten Raum informieren
    public void informUserAboutDeletedPrivateChat(PrivateChat.RemovePrivateChat remPrCh) {
        this.sendObjectToUser(remPrCh);
    }

}